#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <assert.h>

#include <sys/ipc.h>
#include <sys/socket.h>

#include <arpa/inet.h>
#include <netinet/in.h>

#ifndef BUF_SIZE
#define BUF_SIZE 100
#endif

int main(int argc, char *argv[])
{
	struct sockaddr_in str_svr_addr, str_clt_addr;
	int s32_svr_sock, s32_clt_sock, s32_fd, s32_ret;
	unsigned int u32_len;
	unsigned char u8_buf[BUF_SIZE];
	memset(u8_buf, 0, BUF_SIZE);
	
	assert(argc == 3);
	
	str_svr_addr.sin_family		 = AF_INET;
	str_svr_addr.sin_port		 = htons(argv[2]);
	str_svr_addr.sin_addr.s_addr = inet_addr(argv[1]);
	s32_fd = open("File", O_RDONLY);
	if( s32_fd == -1 ) {
		perror("Server app: Unable to open input file");
		exit(1);
	}
	else {
		printf("Server app: File opened\n");
	}
	
	s32_svr_sock = socket(AF_INET,SOCK_STREAM,0);
	if( s32_svr_sock == -1 ) {
		perror("Server app: Unable to create socket");
		exit(2);
	}
	else {
		printf("Server app: Created socket\n");
	}
	s32_ret = bind(s32_svr_sock, (struct sockaddr *) &str_svr_addr, sizeof(str_svr_addr)); 
	if( s32_ret == -1 ) {
		perror("Server app: Failed to bind socket with address");
		exit(3);
	}
	else {
		printf("Server app: Binding done\n");
	}
	s32_ret = listen(s32_svr_sock, 10);
	if( s32_ret == -1 ) {
		perror("Server app: Listening on socket failed");
		exit(4);
	}
	else {
		printf("Server app: Listening for clients\n");
	}
	
	s32_clt_sock = accept( s32_svr_sock, (struct sockaddr *)&str_clt_addr, &u32_len);
	if( s32_clt_sock == -1 ) {
		perror("Server app: Accept failed on server socket");
		exit(5);
	}
	else {
		printf("Server app: Accepting connections\n");
	}
	while((s32_ret = read(s32_fd, (void *)u8_buf, BUF_SIZE)) != 0) {
		write(s32_clt_sock, u8_buf, s32_ret);
	}
	printf("Data from file sent to client %s\n", inet_ntoa(str_clt_addr.sin_addr));
	close(s32_fd);
	close(s32_clt_sock);
	close(s32_svr_sock);
	return 0;
}


